package tracker

import (
	"goDFS/public"
	"math/rand"
	"sync"
	"time"
)

//定义负载均衡器

//负载均衡管理器接口
type BalancerManage interface {
	GetAddress() []*public.StorageAddr     //获取当前全部的负载地址
	RegisterAddr(addr *public.StorageAddr) //注册一个地址到负载均衡器中
	GetAddr() string                       //分配一个地址
}

type LoadBalancer struct {
	Address      []*public.StorageAddr          //全部注册的storage服务器
	heartbeat    func(*public.StorageAddr) bool //用来心跳检测的函数
	sync.RWMutex                                //读写锁

}

//获取全部的Addr
func (l *LoadBalancer) GetAddress() []*public.StorageAddr {
	return l.Address
}

//注册一个地址到负载均衡器中,
func (l *LoadBalancer) RegisterAddr(addr *public.StorageAddr) error {

	//防止重复注册
	for _, v := range l.Address {
		if v == addr {
			return nil
		}
	}

	return nil
}

//获取一个StorageAddr->负载均衡
//可以先试一下随机数算法
func (l *LoadBalancer) GetAddr() string {
	l.RWMutex.RLock()
	defer l.RWMutex.RUnlock()

	n := l.Length()
	//随机数
	index := rand.Intn(n)
	return l.Address[index].GetAddr()
}

//创建负载均衡器,传入一个心跳检测策略
func NewLoadBalancer(f func(*public.StorageAddr) bool) *LoadBalancer {
	rand.Seed(time.Now().Unix()) //写一个随机数种子
	l := new(LoadBalancer)
	l.Address = make([]*public.StorageAddr, 0, 10)
	l.heartbeat = f
	return l

}

//访问地址长度
func (l *LoadBalancer) Length() int {
	return len(l.Address)
}

//删除一个storage地址
func (l *LoadBalancer) DeleteAddr(index int) {
	l.RWMutex.Lock()
	defer l.RWMutex.Unlock()

	if len(l.Address) == 1 {
		l.Address = l.Address[:0]
		return
	}

	l.Address = append(l.Address[:index], l.Address[index+1:]...)

}

//维护Address,以及同步机制
func (l *LoadBalancer) MaintainingAddress() {
	ticker := time.NewTicker(time.Second * 60)

	for true {
		//随机运行一个阻塞任务
		select {
		case <-ticker.C:
			for i, v := range l.Address {
				//做心跳检测
				flag := l.heartbeat(v)
				if !flag {
					l.DeleteAddr(i)
				}

			}
		}
	}

}

//转成可以传输的字符串
func (l *LoadBalancer) ToAddressString() string {
	l.RLock()
	defer l.Unlock()
	str := ""
	for _, v := range l.Address {
		str = str + v.GetAddr() + ";"
	}
	return str
}
